﻿using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Collections.Generic;
using System;
using System.Linq;

namespace FinalPointSet.Model.Model.Knowledge
{
    /// <summary>
    /// 语言类型
    /// </summary>
    public class Language
    {
        public Language() { }
        public Language(int sequence, string name, string logoPath)
        {
            Sequence = sequence;
            Name = name;
            LogoPath = logoPath;
        }
        public int Sequence { get; set; } = 0;
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; } = string.Empty;
        /// <summary>
        /// 图标路径
        /// </summary>
        public string LogoPath { get; set; } = string.Empty;
        /// <summary>
        /// 代码高亮
        /// </summary>
        public HighLight HighLight { get; set; } = new();

        public override string? ToString()
        {
            return $"Sequence={Sequence},Name={Name},LogoPath={LogoPath}";
        }

        public static Language Clone(Language language)
        {
            return new Language()
            {
                Sequence = language.Sequence,
                Name = language.Name,
                LogoPath = language.LogoPath,
                HighLight = language.HighLight,
            };
        }
    }

    public class LanguageConverter : JsonConverter<Language>
    {
        /// <summary>
        /// 语法高亮规则
        /// </summary>
        private readonly List<HighLight> highlights = [];
        public LanguageConverter() { }
        public LanguageConverter(List<HighLight> highlights)
        {
            this.highlights = highlights;
        }
        public override void WriteJson(JsonWriter writer, Language? value, JsonSerializer serializer)
        {
            ArgumentNullException.ThrowIfNull(value);
            //只序列化Name属性
            JObject obj = new()
            {
                { "Sequence", value.Sequence },
                { "Name", value.Name },
                { "LogoPath", value.LogoPath },
                { "HighLight", value.HighLight.Name }
            };
            obj.WriteTo(writer);
        }

        public override Language ReadJson(JsonReader reader, Type objectType, Language? existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            var obj = JObject.Load(reader);
            return Parse(obj, serializer, highlights);
        }

        public static Language Parse(JObject jsonObj, JsonSerializer serializer, List<HighLight> highlights)
        {
            Language result = new();
            // 反序列化单独的属性
            if (jsonObj["Sequence"] is JToken jtSequence)
                result.Sequence = int.Parse(jtSequence.ToString());
            if (jsonObj["Name"] is JToken jtName)
                result.Name = jtName.ToString();
            if (jsonObj["LogoPath"] is JToken jtLogoPath)
                result.LogoPath = jtLogoPath.ToString();

            // 反序列化语言
            if (jsonObj["HighLight"] is JToken jtHighLight && highlights != null && highlights.Count > 0)
            {
                string highLightName = jtHighLight.ToString() ?? string.Empty;
                HighLight hl = highlights.FirstOrDefault(hl => highLightName.Equals(hl.Name), new());
                result.HighLight = HighLight.Copy(hl);
            }

            return result;
        }
    }
}
